/**
 * Startup Manager panel by Jared Brayshaw
 * 
 * Created for Task 150 on FogBugz:
 * https://msoe.fogbugz.com/default.asp?150
 */
package hydrap2p.gui;

import hydrap2p.gui.commands.Cmd_StartupManagerPanel_AddModule;
import hydrap2p.gui.commands.Cmd_StartupManagerPanel_RemoveModule;
import hydrap2p.gui.commands.Cmd_StartupManagerPanel_ShowModuleProperties;
import hydrap2p.gui.commands.CommandInvoker;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableColumn;

import org.apache.thrift.TException;

/**
 * A panel that displays the modules currently recognized.
 * 
 * @author Jared
 */
public class StartupManagerPanel extends JScrollPane implements TableModelListener
{	
	//the table and model for displaying the modules
	private final StartupManagerTableModel model = new StartupManagerTableModel();
	private final JTable table;
	
	//the popup menu and its listener
	private ActionListener contextListener = new MenuItemListener();
	private JPopupMenu contextMenu = new TablePopupMenu();
	
	
	//singleton stuff
	private static volatile StartupManagerPanel instance;
	
	public static synchronized StartupManagerPanel getInstance(){
		if(instance == null){
			synchronized (StartupManagerPanel.class){
				if(instance == null){
					instance = new StartupManagerPanel();
				}
			}
		}
		return instance;
	}
	//end of singleton stuff
	
	
	/**
	 * Constructor that intializes the table and the panels, the refreshes the module list.
	 */
	private StartupManagerPanel(){
		table = new JTable(model);
		
		init();
		
		refreshModuleList();
	}
	
	/**
	 * Initializes all the data for the panel
	 */
	private void init()
	{		
		table.setAutoCreateRowSorter(true);
		//table.setComponentPopupMenu(new TablePopupMenu());
		table.addMouseListener(new PopupListener());
		
		//set some defaults for the table
		TableColumn column;
        
		column = table.getColumnModel().getColumn(0);
        column.setCellRenderer(new TextRenderer());
        column.setMinWidth(65);
        column.setPreferredWidth(250);
        
		column = table.getColumnModel().getColumn(1);
		column.setMinWidth(65);
        column.setMaxWidth(65);
        
        column = table.getColumnModel().getColumn(2);
        column.setMinWidth(75);
        column.setMaxWidth(75);
        
        //give the table a data change listener
        table.getModel().addTableModelListener(this);
		
		setViewportView(table);
		
	}
	
	//getter for the table
	public JTable getTable(){
		return table;
	}
	
	/**
	 * Makes sure the panels are up-to-date
	 */
	public void refreshModuleList()
	{	
		//clear the table
		while (model.getRowCount() > 0)
		{
			model.removeRow(0);
		}
		
		//add the modules
		for (MockModule mm : GUIDataHandler.getInstance().getModules())
		{
			model.addModule(mm, null);
		}
	}

	//update the modules when the table's data changes
    public synchronized void tableChanged(TableModelEvent e) {
        int row = e.getFirstRow();
        int column = e.getColumn();
        
        if (row < 0) return;
        if (column != 1 && column != 2) return;
        
        boolean data = (Boolean)model.getValueAt(row, column);
        
        MockModule mm = GUIDataHandler.getInstance().getModules().get(row);

        if (column == 1) {
        	GUIDataHandler.getInstance().setModuleRunningStatus(row, data);
        	SearchPanel.getInstance().refreshPlugins();		//in case a search plugin was stopped or started
        } else if (column == 2) {
        	GUIDataHandler.getInstance().setModuleAutoStartStatus(row, data);
        }
        
        //
        refreshModuleList();
        //
        
        System.out.println(row + " " + column + ": " + model.getValueAt(row, column));
        System.out.println("Module " + mm.getName() + " now has an 'active' status of " + mm.getStatus() + " and an 'autostart' value of " + mm.getAutostart());
        
        
        /*
        try {
			GUIDataHandler.getInstance().log(GUIDataHandler.LOG_VERBOSE, "Module " + mm.getName(), "'active' status is " + mm.getStatus() + ", 'autostart' value is " + mm.getAutostart());
		} catch (TException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		//*/
    }
    
    class MenuItemListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			if (e.getActionCommand() == "properties")
			{
				CommandInvoker.getInstance().invokeCommand(new Cmd_StartupManagerPanel_ShowModuleProperties());
			}
			else if (e.getActionCommand() == "addModule")
			{
				CommandInvoker.getInstance().invokeCommand(new Cmd_StartupManagerPanel_AddModule());
				System.out.println("Add Module...");
			}
			else if (e.getActionCommand() == "removeModule")
			{
				CommandInvoker.getInstance().invokeCommand(new Cmd_StartupManagerPanel_RemoveModule());
				System.out.println("Remove Module");
			}
		}
	}
    
	private class TablePopupMenu extends JPopupMenu {
        public TablePopupMenu() {
            super();
            addNewStringItem("Properties", "properties");
            addNewStringItem("Add Module...", "addModule");
            addNewStringItem("Remove Module", "removeModule");
            
        }
        @Override
        public void show(Component c, int x, int y) {
            int[] l = table.getSelectedRows();
            super.show(c, x, y);
        }
        
        private void addNewStringItem(String name, String command)
        {
        	JMenuItem temp = new JMenuItem(name);
        	temp.addActionListener(contextListener);
        	temp.setActionCommand(command);
        	add(temp);
        }
    }
	
	class PopupListener extends MouseAdapter {
	    public void mousePressed(MouseEvent e) {
	        maybeShowPopup(e);
	    }

	    public void mouseReleased(MouseEvent e) {
	        maybeShowPopup(e);
	    }

	    private void maybeShowPopup(MouseEvent e) {
	        if (e.isPopupTrigger()) {
	        	contextMenu.show(e.getComponent(), e.getX(), e.getY());
	        }
	    }
	}
}
